#pragma once
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include "ClientMainExecution.hpp"
#include "../interface/ClientExecutionInterface.hpp"
#include "../../tool/ClassReflectionTool.hpp"
#include "../../config/interface/ClientConfigInterface.hpp"
#include "../../type/ClientType.hpp"

class ClientConfigExecution:public ClientExecutionInterface {

private:

     static ClientType::EXECUTION_TYPE executionType;


     ClassReflectionTool::ClassFactory<ClientType::CONFIG_TYPE>* configFactory;
     std::unordered_map<ClientType::CONFIG_TYPE, ClientConfigInterface*> m_configsMap;





public:

     ClientConfigExecution() = default;
     ~ClientConfigExecution() {}

     /**
      *
      * @return
      */
    ClientType::EXECUTION_TYPE getType() const override {
          return ClientConfigExecution::executionType;
     }

private:

     /**
      * 装配配置类终止条件
      * @param config
      */
     void assemblyConfig(ClientConfigInterface* config) {}

     /**
      *
      * @return
      */
     bool startCallBackFunction() override {

          //获取主执行器
          ClientMainExecution* mainExecution = (ClientMainExecution*)this->m_mainExecution ;

          //初始化配置类工厂
          this->configFactory = ClassReflectionTool::ClassFactory<ClientType::CONFIG_TYPE>::getSingleton();

          //获取已经注册的配置类
          std::unordered_set<ClientType::CONFIG_TYPE> registeredConfig = this->configFactory->getClassTypes();

          for (auto& configType : registeredConfig) {

               //检查是否已装配该配置类,没有则装配
               auto configPiar = this->m_configsMap.find(configType);
               if (configPiar == this->m_configsMap.end())
                    this->m_configsMap[configType] = (ClientConfigInterface*)this->configFactory->createClass(configType);

               //装配配置类
               ClientExecutionInterface* execution = mainExecution->getExecutionByExecutionType(this->m_configsMap[configType]->getExecutionType());
               execution->setConfig(this->m_configsMap[configType]);
          }

          return true;
     }

     /**
      *
      * @return
      */
     bool closeCallBackFunction() override {
          return true;
     }


public:
     /**
      *装配配置
      * @tparam CONFIG
      * @tparam CONFIGS
      * @param config
      * @param configs
      */
     template<typename CONFIG ,typename ...CONFIGS>
     void assemblyConfig(CONFIG* config,CONFIGS*... configs) {

          //判断类型是否为ClientConfigInterface
          if (!std::is_same<CONFIG, ClientConfigInterface>::value) return;

          this->m_configsMap[config->getType()] = config;

          //递归调用装配函数
          this->assemblyConfig(configs...);

     }


};

ClientType::EXECUTION_TYPE ClientConfigExecution::executionType = ClientType::EXECUTION_TYPE::CLIENT_CONFIG_EXECUTION;